import axios, { AxiosRequestConfig } from 'axios';
import cookie from 'react-cookies';
import { CMS_BASEURL, TOKEN_COOKIE_NAME, CORGI_PASSPORT_URL } from '../consts/env';
import { HTTP_STATUS } from '../consts/statusCode';
import logUtils from './tools/log_utils';
import tips from './tools/tips_utils';

// axios.defaults.withCredentials = true;
axios.defaults.timeout = 50000;
axios.defaults.headers.common['Content-Type'] = 'application/json';
axios.defaults.baseURL = CMS_BASEURL;

// 中间件 拦截请求-
axios.interceptors.request.use(
  (config) => {
    const crogiToken = cookie.load(`${TOKEN_COOKIE_NAME}`, true);
    const newConfig = config;
    if (!newConfig.headers) {
      newConfig.headers = {};
    }
    newConfig.headers.Authorization = `bearer ${crogiToken}`;

    return newConfig;
  },
  (err) => {
    return Promise.reject(err);
  },
);

axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (err) => {
    if (!err.response) {
      return Promise.reject(err);
    }
    const res = err.response;
    if (res?.status === HTTP_STATUS.AUTHENTICATE) {
      window.location.href = `${CORGI_PASSPORT_URL}/#/login?redirect=${encodeURIComponent(
        window.location.href,
      )}`;
      return Promise.reject(err);
    }
    if (res?.data?.message) tips.error(`${res?.data?.message}`);
    return Promise.reject(err);
  },
);

const safeRequest = <T>(url: string, options?: AxiosRequestConfig): Promise<T> => {
  return new Promise((resolve, reject) => {
    axios({
      method: 'GET',
      ...options,
      url,
    }).then(
      (res) => {
        if (res) {
          resolve(res.data);
        } else {
          reject(res);
        }
      },
      (err) => {
        logUtils.e(err);
        reject(err);
      },
    );
  });
};

/**
 * get
 * @param url
 * @param opts
 * @returns {Promise}
 */
const get = <T>(url: string, opts?: AxiosRequestConfig): Promise<T> => {
  return safeRequest<T>(url, opts);
};

/**
 * post
 * @param url
 * @param opts
 * @returns {Promise}
 */
const post = <T>(url: string, opts?: AxiosRequestConfig): Promise<T> => {
  return safeRequest<T>(url, {
    ...opts,
    method: 'POST',
  });
};

/**
 * put
 * @param url
 * @param opts
 * @returns {Promise}
 */
const put = <T>(url: string, opts?: AxiosRequestConfig): Promise<T> => {
  return safeRequest<T>(url, {
    ...opts,
    method: 'PUT',
  });
};

/**
 * del
 * @param url
 * @param opts
 * @returns {Promise}
 */
const del = <T>(url: string, opts?: AxiosRequestConfig): Promise<T> => {
  return safeRequest<T>(url, {
    ...opts,
    method: 'DELETE',
  });
};

const request = {
  get,
  post,
  put,
  del,
};
export default request;
